/*
 * tools.cpp
 *
 *  Created on: 30 janv. 2011
 *      Author: quentin
 */

#include "tools.hpp"


double deltaTimeToMS(double deltaTime, int tempo, int division){

    double result = 0;

    result = deltaTime * 1000 * ( 60.0 / ((60000000 / tempo) * division));

    return result;


}

QString recupNomFichierSelectionne(const QString & cheminFichier){
    unsigned int i = (cheminFichier.length()-1);
    QString nomFichier;

    while(cheminFichier.at(i) != '/'){
        nomFichier.push_front(cheminFichier.at(i));
        i--;
    }

    return nomFichier;
}

double getTempo(int* tab, int taille){

    double result = 0;

    int offset = (taille-1)*8;
    int temp = 0;

    //For each element of tab
    for(int i =0; i<taille; i++){

        //Moving bits the the left.
        temp = tab[i] << offset;

        result += temp;

        //Decreasing offset by one byte
        offset-=8;
    }


    return result;
}

MidiFile* loadMidi(MidiFile* midiFile, const char* nomMidi){

    std::ifstream fichier;
    fichier.open(nomMidi);

    unsigned char *buffer = NULL;


    // get length of file:
    fichier.seekg (0, std::ios::end);//set the pointer at end of file
    int lenght = fichier.tellg();// return the position of pointer
    fichier.seekg (0, std::ios::beg);//set the pointer at begining of file
    std::cout << "My length is "<<lenght << std::endl;


    buffer = new unsigned char[lenght];
    fichier.read((char*)buffer, lenght);

    midiFile = new MidiFile();
    midiFile->setHeaderChunk(buffer);
    midiFile->setTrackChunks(buffer);
    midiFile->setNoteDuration();
    midiFile->viewNoteDuration();



    return midiFile;
}

void getCollectionNotes(int note){

}


void getInfoMidi(MidiFile* myMidiFile, InfosMidi* infos){
    //Nb de notes ou nb de battements?
    double currentTime;
    double nbNotes = 0;
    double maxTime = 0;
    std::vector< std::pair<double, double> > vecTempo;

    //Par défaut, le tempo vaut 500000, soit 120bpm
    double currentTempo = 500000;

    for(int i=0 ; i< myMidiFile->myHeaderChunk.getNumberOfTracks() ; i++){

        unsigned int j=0;
        currentTime = 0;

        while(j<myMidiFile->tabTrackChunk[i].eventVector.size()){

            for(unsigned int iTempo = 0 ; iTempo < vecTempo.size() ; iTempo++){
                if(currentTime > vecTempo.at(iTempo).first){
                    //std::cout<< "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<<std::endl;
                    //std::cout<< "time? = "<<vecTempo.at(iTempo).first<< "tempo? = " << vecTempo.at(iTempo).second <<std::endl;
                    currentTempo = vecTempo.at(iTempo).second;
                    //std::cout<< "currentTempo "<<currentTempo<<std::endl;
                }
            }

            //Si c'est un midi event
            if(!strcmp("9MidiEvent", typeid(*myMidiFile->tabTrackChunk[i].eventVector.at(j)).name())){

                MidiEvent* evt = static_cast<MidiEvent*>(myMidiFile->tabTrackChunk[i].eventVector.at(j));

                if(evt->status >= 144 && evt->status <= 159){
                    nbNotes++;
                    getCollectionNotes(evt->status);
                }
                currentTime += deltaTimeToMS(evt->deltaTime, currentTempo, myMidiFile->myHeaderChunk.getDivision())/1000;

            }
            //Si c'est un meta event
            else{
                MetaEvent* evt = static_cast<MetaEvent*>(myMidiFile->tabTrackChunk[i].eventVector.at(j));

                currentTime += deltaTimeToMS(evt->deltaTime, currentTempo, myMidiFile->myHeaderChunk.getDivision())/1000;

                //std::cout<<"meta event type : "<< evt->metaType <<std::endl;
                //Si j'ai un changement de tempo
                if(evt->metaType==81){
                    currentTempo = getTempo(evt->data, evt->vLength);

                    vecTempo.push_back( std::make_pair(currentTime, currentTempo) );

                    //std::cout<<"!!! changement de tempo! currentTempo : "<< currentTempo << " et currentTime " << currentTime << std::endl;

                }
                else if(evt->metaType==47){
                    std::cout<<"fin de piste ! currentTime : "<< currentTime << " et tempo : "<< currentTempo <<std::endl;
                    if(maxTime<currentTime){
                        maxTime = currentTime;
                    }

                }
            }
            j++;
        }
    }

    infos->setDureeMidi(maxTime);
    infos->setNbNotes(nbNotes);
    //infos->setAmbitus(ambitusMidi); // A FAIRE !!!

}

QString formaterCommeNomProjet(const QString & nomDepart){
    QString nomBonFormat = nomDepart;
    if(nomDepart.endsWith("mid") || nomDepart.endsWith("MID")){
        nomBonFormat.truncate((nomBonFormat.size()-3));
        nomBonFormat.append("jsx");
    }else if(nomDepart.endsWith("midi") || nomDepart.endsWith("MIDI")){
        nomBonFormat.truncate((nomBonFormat.size()-4));
        nomBonFormat.append("jsx");
    }

    return nomBonFormat;
}
